package Ms

import (
	"errors"
	"fmt"
	"db2s/global"
	"db2s/parDef"
	"db2s/ref"
	"strings"
)

type columnMeta struct {
	DatabaseName  string `json:"databaseName"`
	TableName     string `json:"tableName"`
	ColumnName    string `json:"columnName"`
	ColumnType    string `json:"columnType"` //原始的数据类型，不带长度的
	ColumnSeq     string `json:"columnSeq"`
	IsNull        string `json:"isNull"` //
	Charset       string `json:"charset"`
	CollationName string `json:"collationName"`
	ColumnComment string `json:"columnComment"`
	ColumnDefault string `json:"columnDefault"`
	DataType      string `json:"dataType"` //处理过的数据类型，带长度的
	DataLength    int64  `json:"dataLength"`
	CharLength    int64  `json:"charLength"`
	DataPrecision int64  `json:"dataPrecision"`
	DataScale     int64  `json:"dataScale"`
	Invisible     bool   `json:"invisible"`
	AutoIncrement bool
}

func colMetaMapInit(s columnMeta) parDef.ColMetaMapS {
	return parDef.ColMetaMapS{
		DatabaseName:     s.DatabaseName,
		TableName:        s.TableName,
		ColumnName:       s.ColumnName,
		Charset:          s.Charset,
		CollationName:    s.CollationName,
		ColAutoIncrement: s.AutoIncrement,
		Invisible:        s.Invisible,
		ColumnComment:    s.ColumnComment,
		ColumnSeq:        s.ColumnSeq,
	}
}
func ExtractTypeName(s1 string) string {
	var bef, aft string
	if p := strings.Index(s1, "("); p != -1 {
		bef = s1[:p]
	}
	if p := strings.Index(s1, ")"); p != -1 {
		aft = s1[p+1:]
	}
	if len(bef) > 0 || len(aft) > 0 {
		return strings.TrimSpace(fmt.Sprintf("%v%v", bef, aft))
	}
	return s1
}
func charTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	res = p
	res.TypeBelong = "char"
	res.Type.ColTypeMap = fmt.Sprintf("char(show)")
	switch strings.ToUpper(m.ColumnType) {
	case "CHAR", "NCHAR":
		/*
			定义长度: CHAR 类型需要在定义时指定长度,最大长度为 8000 个字符。例如, CHAR(10) 表示最多可以存储 10 个字符的字符串。
			存储空间: CHAR 类型会占用固定的存储空间,即定义的长度个字节。例如, CHAR(10) 类型会占用 10 个字节的存储空间。
		*/
		res.Type.MaxValue = 8000
		res.Type.ShowValue = m.CharLength
		res.Type.UseByte = m.CharLength
	case "VARCHAR", "NVARCHAR":
		/*
			定义长度: VARCHAR 类型需要在定义时指定最大长度,最大长度为 8000 个字符。例如, VARCHAR2(50) 表示最多可以存储 50 个字符的字符串。
		*/
		res.Type.MaxValue = 8000
		res.Type.Variable = true
		res.Type.ShowValue = m.CharLength
		res.Type.UseByte = m.CharLength
	default:
		err = ref.ErrAddPrintf("charTypeMap", errors.New(fmt.Sprintf("type not match. curry type is %v", m.ColumnType)))
	}
	return
}
func iSVarchar(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	switch strings.ToUpper(m.ColumnType) {
	case "CHAR", "NCHAR", "VARCHAR", "NVARCHAR":
		res, err = charTypeMap(m, p)
	case "BINARY", "VARBINARY", "IMAGE", "UNIQUEIDENTIFIER": //二进制类型
		res, err = lobTypeMap(m, p)
	case "TEXT", "NTEXT", "XML": //大文本类型
		res, err = textTypeMap(m, p)
	default:
		err = ref.ErrAddPrintf("iSVarchar", errors.New(fmt.Sprintf("not match type %v", m.DataType)))
	}
	return
}
func intTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	res = p
	if strings.Contains(strings.ToUpper(m.DataType), "UNSIGNED") {
		res.Type.Symbol = true
	}
	res.TypeBelong = "numerical"
	switch strings.ToUpper(m.ColumnType) {
	case "BIT":
		/*
			存储u空间：BIT(M) 可以存储 M 位的二进制数据, 其中 M 的取值范围是 1 到 64  默认值：如果不指定位数 M, 默认为 BIT(1)。
		*/
		res.TypeBelong = "bit"
		res.Type.MinValue = 1
		res.Type.MaxValue = 1
		res.Type.ShowValue = m.DataPrecision
	case "TINYINT":
		res.Type.MinValue = -128
		res.Type.MaxValue = 127
		res.Type.ShowValue = 127
		res.Type.UseByte = 1
		res.Type.ColTypeMap = "int"
	case "SMALLINT":
		res.Type.MinValue = -32768
		res.Type.MaxValue = 32767
		res.Type.ShowValue = 32767
		res.Type.UseByte = 2
		res.Type.ColTypeMap = "int"
	case "INT":
		res.Type.MinValue = -2147483648
		res.Type.MaxValue = 2147483647
		res.Type.ShowValue = 2147483647
		res.Type.UseByte = 4
		res.Type.ColTypeMap = "int"
	case "BIGINT":
		res.Type.MinValue = -9223372036854775808
		res.Type.MaxValue = 9223372036854775807
		res.Type.ShowValue = 9223372036854775807
		res.Type.UseByte = 8
		res.Type.ColTypeMap = "int"
	default:
		err = ref.ErrAddPrintf("intTypeMap", errors.New(fmt.Sprintf("type not match. curry type is %v", m.ColumnType)))
	}
	return
}
func floatTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	res = p
	res.TypeBelong = "float"
	res.Type.ColTypeMap = "float(precision)"
	if strings.Contains(strings.ToLower(m.DataType), "unsigned") {
		res.Type.Symbol = true
	}
	res.Type.ShowValue = m.DataPrecision
	switch strings.ToUpper(m.ColumnType) {
	case "REAL":
		res.TypeBelong = "float"
		res.Type.MinValue = 0
		res.Type.MaxValue = 23
		res.Type.UseByte = 4
	case "FLOAT":
		res.TypeBelong = "double"
		res.Type.MinValue = 0
		res.Type.MaxValue = 53
		res.Type.UseByte = 8
	default:
		err = ref.ErrAddPrintf("floatTypeMap", errors.New(fmt.Sprintf("type not match. curry type is %v", m.ColumnType)))
	}
	return
}
func decimalTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	//number(p,s)  如何不指定p和s，则默认为number(38,0);即最大38位整数
	//如何只指定p，则s默认为0，即整数。例如number(10)，表示10位整数
	//同时指定p和s，则p必须大于等于s，例如number(10,2)，表示最多10位数字，其中包括两位小数
	//s可以是负数，表示小数点左边的位数。例如number(10,-2)表示10位整数，且最多保留到百位
	res = p
	res.TypeBelong = "decimal"
	res.Type.ColTypeMap = "decimal(precision,scale)"
	if strings.Contains(strings.ToLower(m.DataType), "unsigned") {
		res.Type.Symbol = true
	}
	res.Type.UseByte = m.DataPrecision + 1
	switch {
	case m.DataPrecision == 0 && m.DataScale == 0: //不定长整数位 number、number(*,0)、number(*)
		res.Type.Precision = 40
		res.Type.ColTypeMap = "decimal(max,max)"
	case m.DataPrecision > 0 && m.DataScale == 0:
		res.Type.Precision = m.DataPrecision
	case m.DataPrecision == 0 && m.DataScale > 0: //number(*,5)
		res.Type.Precision = 38
		res.Type.Scale = m.DataScale
	case m.DataPrecision > 0 && m.DataScale > 0 && m.DataPrecision < m.DataScale: //number(10,20)
		res.Type.Precision = m.DataPrecision + m.DataScale
		res.Type.Scale = m.DataScale
	case m.DataPrecision == 0 && m.DataScale < 0: //负数开头，表示只有整数，没有小数。例如：number(*,-2)
		res.Type.Precision = 40
	case m.DataPrecision > 0 && m.DataScale > 0: // number(DataPrecision,Scale)
		res.Type.Precision = m.DataPrecision
		res.Type.Scale = m.DataScale
	case m.DataPrecision > 0 && m.DataScale < 0: //负数开头，表示只有整数，没有小数。例如：number(10,-2)
		res.Type.Precision = m.DataPrecision
	default:
		err = ref.ErrAddPrintf("decimalTypeMap", errors.New(fmt.Sprintf("type not match. curry type is %v,%v,%v", m.DataType, m.DataPrecision, m.DataScale)))
	}
	return
}
func timeTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	res = p
	res.TypeBelong = "time"
	switch strings.ToUpper(m.ColumnType) {
	case "DATE":
		/*
			DATE 类型:
				存储日期,格式为 YYYY-MM-DD。
				取值范围从 1000-01-01 到 9999-12-31。
				占用 3 个字节的存储空间。
		*/
		res.Type.UseByte = 3
		res.Type.ColTypeMap = "year-month-day"
	case "TIME":
		/*
			TIME 类型:
					存储时间,格式为 HH:MM:SS。
					取值范围从 -838:59:59 到 838:59:59。
					占用 3 个字节的存储空间。
				MySQL 中 TIME(n) 数据类型的 n 最大值是 6。也就是说,MySQL 支持的最大时间值小数精度为 6 位小数。
			具体解释如下:
				TIME(n) 数据类型用于存储时间值,其中 n 表示小数部分的位数。
					当 n 取值为 0 时,时间值精确到秒。
					当 n 取值为 1 到 6 时,时间值精确到小数点后 1 到 6 位。
					n 的最大值为 6，这意味着 TIME(6) 可以存储时间值精确到微秒(百万分之一秒)。
			例如:
					TIME(0) 存储为 'HH:MM:SS'
					TIME(3) 存储为 'HH:MM:SS.sss'
					TIME(6) 存储为 'HH:MM:SS.sssSss'
					需要注意的是,虽然 MySQL 支持 TIME(n) 最大 n 值为 6，但实际使用时根据需要选择合适的精度即可。过高的时间值精度可能会占用更多的存储空间,并且在某些情况下可能无法提供额外的价值。
		*/
		res.Type.UseByte = 3
		switch m.DataScale {
		case 0:
			res.Type.ColTypeMap = "hour:minute:second"
		case 1:
			res.Type.ColTypeMap = "hour:minute:second.milli(1)"
		case 2:
			res.Type.ColTypeMap = "hour:minute:second.milli(2)"
		case 3:
			res.Type.ColTypeMap = "hour:minute:second.milli(3)"
		case 4:
			res.Type.ColTypeMap = "hour:minute:second.micro(1)"
		case 5:
			res.Type.ColTypeMap = "hour:minute:second.micro(2)"
		case 6:
			res.Type.ColTypeMap = "hour:minute:second.micro(3)"
		case 7:
			res.Type.ColTypeMap = "hour:minute:second.nano(1)"
		}
	case "SMALLDATETIME":
		res.Type.UseByte = 8
		res.Type.ColTypeMap = "year-month-day hour:minute:second"
	case "DATETIME":
		res.Type.ColTypeMap = "year-month-day hour:minute:second.milli(3)"
		res.Type.UseByte = 8
	case "DATETIME2":
		/*
			DATETIME 类型:
				存储日期和时间,格式为 YYYY-MM-DD HH:MM:SS。
				取值范围从 1000-01-01 00:00:00 到 9999-12-31 23:59:59。
				占用 8 个字节的存储空间。
		*/
		res.Type.UseByte = 8
		switch m.DataScale {
		case 0:
			res.Type.UseByte = 6
			res.Type.ColTypeMap = "year-month-day hour:minute:second"
		case 1:
			res.Type.UseByte = 6
			res.Type.ColTypeMap = "year-month-day hour:minute:second.milli(1)"
		case 2:
			res.Type.UseByte = 6
			res.Type.ColTypeMap = "year-month-day hour:minute:second.milli(2)"
		case 3:
			res.Type.UseByte = 7
			res.Type.ColTypeMap = "year-month-day hour:minute:second.milli(3)"
		case 4:
			res.Type.UseByte = 7
			res.Type.ColTypeMap = "year-month-day hour:minute:second.micro(1)"
		case 5:
			res.Type.UseByte = 8
			res.Type.ColTypeMap = "year-month-day hour:minute:second.micro(2)"
		case 6:
			res.Type.UseByte = 8
			res.Type.ColTypeMap = "year-month-day hour:minute:second.micro(3)"
		default:
			res.Type.UseByte = 8
			res.Type.ColTypeMap = "year-month-day hour:minute:second.micro(3)"
		}

	case "DATETIMEOFFSET":
		/*
			MySQL 中的 TIMESTAMP 数据类型是一种特殊的日期时间类型,具有以下特点:
			定义:
				TIMESTAMP 用于存储日期和时间信息,包括年、月、日、时、分、秒。时间戳的格式为 YYYY-MM-DD HH:MM:SS。
			范围:
				TIMESTAMP 的取值范围从 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC。
			存储大小:
				TIMESTAMP 类型占用 4 个字节的存储空间。
			时区支持:
				TIMESTAMP 值是以 UTC 时区存储的。在插入或查询时,MySQL 会根据当前会话的时区自动进行转换。
			默认值:
				如果不指定 TIMESTAMP 列的默认值,则默认为当前时间戳。可以通过 DEFAULT CURRENT_TIMESTAMP 指定默认值为当前时间戳。
			自动更新:
				TIMESTAMP 列可以被定义为在行更新时自动更新为当前时间戳。通过 ON UPDATE CURRENT_TIMESTAMP 可以实现自动更新。
			与 DATETIME 的区别:
				DATETIME 是一种独立的日期时间类型,不受时区影响。TIMESTAMP 受时区影响,存储的是 UTC 时间,查询时会根据会话时区转换。
		*/
		res.TypeBelong = "timestamp"
		switch m.DataScale {
		case 0:
			res.TypeBelong = "time"
			res.Type.ColTypeMap = "year-month-day hour:minute:second"
			res.Type.UseByte = 8
		case 1:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.milli(1).utc"
			res.Type.UseByte = 8
		case 2:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.milli(2).utc"
			res.Type.UseByte = 8
		case 3:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.milli(3).utc"
			res.Type.UseByte = 9
		case 4:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.micro(1).utc"
			res.Type.UseByte = 9
		case 5:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.micro(2).utc"
			res.Type.UseByte = 10
		case 6:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.micro(3).utc"
			res.Type.UseByte = 10
		case 7:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.nano(1).utc"
			res.Type.UseByte = 10
		case 8:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.nano(2).utc"
			res.Type.UseByte = 10
		case 9:
			res.Type.ColTypeMap = "year-month-day hour:minute:second.nano(3).utc"
			res.Type.UseByte = 10
		}
	default:
		err = ref.ErrAddPrintf("timeTypeMap", errors.New(fmt.Sprintf("type not match. curry type is %v,%v,%v", m.DataType, m.DataPrecision, m.DataScale)))
	}
	return
}
func textTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	res = p
	res.TypeBelong = "text"
	res.Type.ColTypeMap = "text"
	switch strings.ToUpper(m.ColumnType) {
	case "TEXT", "XML", "VARCHAR", "NVARCHAR":
		/*
			LONG 数据类型是 Oracle 数据库中用于存储大文本数据的一种数据类型。最大长度为 2 GB。这意味着它可以存储最多 2 GB 的文本数据。要换算成字符数,需要考虑字符编码。以 UTF-8 编码为例:1 个英文字符占 1 个字节 1 个中文字符占 3 个字节
			需要注意的是, Oracle 不建议再使用 LONG 数据类型,而是建议使用更新的 CLOB 数据类型。CLOB 数据类型的最大长度为 4 GB,比 LONG 类型增加了一倍的容量。同时 CLOB 在性能、可操作性等方面也更加优秀。
		*/
		res.Type.MaxValue = 2147483647
		res.Type.ShowValue = 2147483647
		res.Type.UseByte = 2147483647
	case "NTEXT":
		res.Type.MaxValue = 1073741823
		res.Type.ShowValue = 1073741823
		res.Type.UseByte = 1073741823
	default:
		err = ref.ErrAddPrintf("textTypeMap", errors.New(fmt.Sprintf("type not match. curry type is %v,%v,%v", m.DataType, m.DataPrecision, m.DataScale)))
	}
	return
}
func lobTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	res = p
	res.TypeBelong = "lob"
	switch strings.ToUpper(m.ColumnType) {
	case "BINARY":
		res.Type.MaxValue = 8000
		res.Type.ShowValue = m.DataPrecision
		res.Type.ColTypeMap = "binary(show)"
		res.Type.UseByte = 4294967296
	case "UNIQUEIDENTIFIER":
		res.TypeBelong = "char"
		res.Type.MaxValue = 18
		res.Type.ShowValue = 18
		res.Type.ColTypeMap = "char(show)"
		res.Type.UseByte = 18
	case "VARBINARY":
		res.Type.MaxValue = 8000
		res.Type.ShowValue = m.DataPrecision
		res.Type.ColTypeMap = "binary(show)"
		res.Type.UseByte = 8000
	case "IMAGE":
		res.Type.MaxValue = 2147483647
		res.Type.ShowValue = 2147483647
		res.Type.ColTypeMap = "binary"
		res.Type.UseByte = 2147483647
	default:
		err = ref.ErrAddPrintf("lobTypeMap", errors.New(fmt.Sprintf("type not match. curry type is %v,%v,%v", m.DataType, m.DataPrecision, m.DataScale)))
	}
	return
}
func siteTypeMap(_ columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	res = p
	res.TypeBelong = "gis"
	res.Type.ColTypeMap = "geometry"
	return
}
func notISVarchar(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	switch strings.ToUpper(m.ColumnType) {
	case "BIT", "TINYINT", "SMALLINT", "INT", "BIGINT": //整数数值类型
		res, err = intTypeMap(m, p) //case "NUMBER", "DECIMAL", "NUMERIC": //定长数值
	case "FLOAT", "REAL":
		res, err = floatTypeMap(m, p)
	case "DECIMAL", "NUMERIC", "MONEY", "SMALLMONEY": //定长数值类型:
		res, err = decimalTypeMap(m, p)
	case "DATE", "TIME", "SMALLDATETIME", "DATETIME", "DATETIME2", "DATETIMEOFFSET": //时间类型
		res, err = timeTypeMap(m, p)
	case "VARCHAR", "NVARCHAR", "TEXT", "NTEXT", "XML": //大文本类型
		res, err = textTypeMap(m, p)
	case "BINARY", "VARBINARY", "IMAGE", "UNIQUEIDENTIFIER": //二进制类型
		res, err = lobTypeMap(m, p)
	case "GEOGRAPHY", "GEOMETRY":
		res, err = siteTypeMap(m, p)
	default:
		err = ref.ErrAddPrintf("notISVarchar", errors.New(fmt.Sprintf("not match type %v", m.DataType)))
	}
	return
}
func colTypeMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS, err error) {
	//字符串类型包含char，varchar2,nchar,nvarchar2,clob,nclob
	//只有char,nchar,varchar2,nvarchar2涉及到长度
	//char和nchar是定长的，如果输入的字符串长度小于size，则会用空格填充
	//nLob和lob的char_length=0
	if m.CharLength > 0 { //数值类型 和lob类型
		if res, err = iSVarchar(m, p); err != nil {
			err = ref.ErrAddPrintf("colTypeMap", err)
			return
		}
		return
	}
	if res, err = notISVarchar(m, p); err != nil {
		err = ref.ErrAddPrintf("colTypeMap", err)
		return
	}
	return
}
func colNullMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS) {
	//是否允许为null，yes表示为允许，no表示不允许
	res = p
	switch m.IsNull {
	case "Y":
		res.ColNullMap = "YES"
	case "N":
		res.ColNullMap = "NO"
	}
	return
}
func LeftRightSingleQuotationMarks(defaultVal string) (newDefaultVal string) {
	newDefaultVal = defaultVal
	if strings.HasPrefix(defaultVal, "'") && strings.HasSuffix(defaultVal, "'") {
		newDefaultVal = defaultVal[1 : len(defaultVal)-1]
	}
	switch {
	case strings.HasPrefix(defaultVal, "(") && strings.HasSuffix(defaultVal, ")"):
		newDefaultVal = defaultVal[1 : len(defaultVal)-1]
	case !strings.HasPrefix(defaultVal, "(") && strings.Contains(defaultVal, "(") && strings.HasSuffix(defaultVal, ")"):
		if r := strings.Index(defaultVal, "("); r != -1 {
			newDefaultVal = defaultVal[:r]
		}
	default:
		newDefaultVal = defaultVal
	}
	//判断default 值是否包含N''
	if strings.HasPrefix(newDefaultVal, "N'") && strings.HasSuffix(newDefaultVal, "'") {
		newDefaultVal = newDefaultVal[2 : len(newDefaultVal)-1]
	}
	return
}
func colDefaultMap(m columnMeta, p parDef.ColMetaMapS) (res parDef.ColMetaMapS) {
	res = p
	var oldDefaultValue = strings.ToUpper(m.ColumnDefault)
	newDefaultVal := strings.ToUpper(LeftRightSingleQuotationMarks(oldDefaultValue))
	switch {
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "CURRENT_TIMESTAMP"):
		p.ColDefaultMap = "year-month-day hour:minute:second.micro(3).utc"
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "CURRENT_DATE"), strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "NOW()"):
		p.ColDefaultMap = "year-month-day hour:minute:second"
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "CURRENT_TIME"):
		p.ColDefaultMap = "hour:minute:second"
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "USER()"):
		p.ColDefaultMap = "current_user@host"
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "CURRENT_USER()"):
		p.ColDefaultMap = "current_user"
	case strings.HasSuffix(strings.ToUpper(m.ColumnDefault), "SYSTEM_USER()"):
		p.ColDefaultMap = "current_sys_user"
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "UUID()"):
		p.ColDefaultMap = "uuid"
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "RAND()"):
		p.ColDefaultMap = "randValue"
	case strings.HasPrefix(strings.ToUpper(m.ColumnDefault), "CONNECTION_ID()"):
		p.ColDefaultMap = "current_id"
	default:
		p.ColDefaultMap = newDefaultVal
	}
	return
}
func (cm ColumnMe) MetaMap(parameter parDef.Parameter) (result global.Return, err error) {
	if parameter.Meta == nil {
		return
	}
	var colMetaS []columnMeta
	var res []parDef.ColMetaMapS
	for _, v := range parameter.Meta.([]map[string]any) {
		vv := mapNullActive(v)
		if strings.EqualFold(fmt.Sprintf("%v", vv["autoIncrement"]), "NULL") {
			vv["autoIncrement"] = false
		} else {
			vv["autoIncrement"] = true
		}
		var p columnMeta
		if err = ref.MapToStruct(vv, &p); err != nil {
			err = ref.ErrAddPrintf("MetaMap", err)
			return
		}
		colMetaS = append(colMetaS, p)
	}
	for _, v := range colMetaS {
		var p parDef.ColMetaMapS
		if p, err = colTypeMap(v, colMetaMapInit(v)); err != nil {
			err = ref.ErrAddPrintf("MetaMap", err)
			return
		}
		p = colNullMap(v, p)
		p = colDefaultMap(v, p)
		p.ColumnSeq = v.ColumnSeq
		res = append(res, p)
	}
	result.Result = res
	return
}
func metaBaseInit(meta any) (result MetaBaseInitResult, err error) {
	result = MetaBaseInitResult{}
	if result.columnMeta, err = columnMetaBaseInit(meta.(map[string]any)["columnMe"]); err != nil {
		err = ref.ErrAddPrintf("metaBaseInit", err)
		return
	}
	switch meta.(map[string]any)["columnMetaMap"].(type) {
	case []parDef.ColMetaMapS:
		result.columnMetaMap = meta.(map[string]any)["columnMetaMap"].([]parDef.ColMetaMapS)
	}
	switch meta.(map[string]any)["indexMe"].(type) {
	case []parDef.IndexColumnMe:
		result.indexMeta = func() (res []*parDef.IndexColumnMe) {
			for _, v := range meta.(map[string]any)["indexMe"].([]parDef.IndexColumnMe) {
				res = append(res, &v)
			}
			return
		}()
	}
	switch meta.(map[string]any)["partMe"].(type) {
	case parDef.PartMetaData:
		result.partMe = meta.(map[string]any)["partMe"].(parDef.PartMetaData)
	}
	switch meta.(map[string]any)["commentMe"].(type) {
	case string:
		result.Comment = meta.(map[string]any)["commentMe"].(string)
	}
	return
}
func (cm ColumnMe) ColumnAttributeMapClip(parameter parDef.Parameter) (result map[string]parDef.ColMetaMapS, err error) {
	var metaBase MetaBaseInitResult
	if metaBase, err = metaBaseInit(parameter.Meta); err != nil {
		err = ref.ErrAddPrintf("ColumnAttributeMapClip", err)
		return
	}
	result = make(map[string]parDef.ColMetaMapS)
	for _, v := range metaBase.columnMetaMap {
		var key = v.ColumnName
		if _, ok := result[key]; !ok {
			result[key] = v
		}
	}
	return
}
